
package com.yimixian.app.mvp.basehttp;

import com.yimixian.app.R;
import com.yimixian.app.SystemFramework;
import com.yimixian.app.rest.response.Error;
import com.yimixian.app.util.NetworkUtils;
import com.yimixian.app.util.SharedPreferencesHelper;
import com.yimixian.app.util.Strings;
import com.ymx.sdk.mvp.Presenter;

import org.json.JSONException;
import org.json.JSONObject;

import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

import android.support.v4.util.SparseArrayCompat;
import android.text.TextUtils;

public abstract class BaseHttpPresenter<T extends BaseHttpMvpView> implements
        Callback<Response>, Presenter<T> {
    private T mMvpView;

    @Override
    public void attachView(T mvpView) {
        mMvpView = mvpView;
    }

    @Override
    public void detachView() {
        mMvpView = null;
    }

    public boolean isViewAttached() {
        return mMvpView != null;
    }

    public T getMvpView() {
        return mMvpView;
    }

    public void checkViewAttached() {
        if (!isViewAttached())
            throw new MvpViewNotAttachedException();
    }

    public static class MvpViewNotAttachedException extends RuntimeException {
        public MvpViewNotAttachedException() {
            super("Please call Presenter.attachView(MvpView) before" +
                    " requesting data to the Presenter");
        }
    }

    private SparseArrayCompat<String> mRequestKeyArray = new SparseArrayCompat<>();

    public abstract void initRequestAPI(String requestKeys);

    public abstract void onHttpSuccess(String url, JSONObject responseJson);

    public abstract void OnHttpFailure(String url, String errorMessage, boolean errorFromUs);

    public abstract void fetchDataFromNetwork(String key);

    public void getRawResponse(String url, Response response) {
    }

    /**
     * retrofit sucess
     *
     * @param baseResponse
     * @param response
     */
    @Override
    public void success(Response baseResponse, Response response) {
        String url = response.getUrl();
        String json = "";
        JSONObject jsonObject = null;
        getRawResponse(url, response);
        try {
            json = Strings.inputStream2String(response.getBody().in());
        } catch (Exception e) {
            e.printStackTrace();
            OnHttpFailure(url, SystemFramework.getInstance().getGlobalContext()
                    .getString(R.string.io_error), false);
            return;
        }

        if (!TextUtils.isEmpty(json)) {
            try {
                jsonObject = new JSONObject(json);

            } catch (JSONException e) {
                e.printStackTrace();
                OnHttpFailure(url, SystemFramework.getInstance().getGlobalContext()
                        .getString(R.string.json_error), false);
                return;
            }
        }

        // 返回error信息
        if (jsonObject != null) {
            JSONObject errorObject = jsonObject.optJSONObject("error");
            if (errorObject != null) {// 返回错误信息
                com.yimixian.app.rest.response.Error error = new Error();
                error.code = errorObject.optInt("code");
                error.message = errorObject.optString("message");
                if (!TextUtils.isEmpty(error.message)) {
                    OnHttpFailure(url, error.message, true);
                    return;
                }
            }
        }

        onHttpSuccess(url, jsonObject);
    }

    /**
     * set request id (not required)
     *
     * @param index
     * @param requestKey
     */
    public void setRequestKey(int index, String requestKey) {
        mRequestKeyArray.put(index, requestKey);
    }

    /**
     * get request id (not required)
     *
     * @param index
     * @return
     */
    public String getRequestKeyByIndex(int index) {
        if (mRequestKeyArray != null) {
            return mRequestKeyArray.get(index);
        } else {
            return "";
        }
    }

    public int getRequestKeySize() {
        if (mRequestKeyArray != null) {
            return mRequestKeyArray.size();
        } else {
            return 0;
        }
    }

    /**
     * if need,override this fun,fetch local data from db or file
     *
     * @param key
     * @return
     */
    public String fetchDataFromLocal(String key) {
        return SharedPreferencesHelper.getString(key);
    }

    /**
     * if need,override this fun,save data to db or file
     *
     * @param key
     * @param responseJson
     */
    public void saveData2Local(String key, String responseJson) {
        SharedPreferencesHelper.commitString(key, responseJson);
    }

    /**
     * fetch data from local or network
     *
     * @param isFetchFromNetWork
     * @param requestKey
     */
    public void fetchData(boolean isFetchFromNetWork, String requestKey) {
        if (isFetchFromNetWork) {
            if (checkNetWorkState()) {
                fetchDataFromNetwork(requestKey);
            }
        } else {
            fetchDataFromLocal(requestKey);
        }
    }

    /**
     * check network is avaliable for better battery performance
     *
     * @return
     */
    public boolean checkNetWorkState() {
        if (NetworkUtils.isNetworkAvaliable(SystemFramework.getInstance().getGlobalContext())) {
            return true;
        } else {
            getMvpView().showNetWorkUnavailableUI();
            return false;
        }
    }

    /**
     * retrofit failure
     *
     * @param error
     */
    @Override
    public void failure(RetrofitError error) {
        OnHttpFailure(error.getUrl(), error.getMessage(), false);
    }

}
